package dao.CourseDao;

import common.model.Entity.Semester;
import common.model.Entity.Student;
import common.model.Entity.courseEntity.Course;
import common.model.Entity.courseEntity.CourseSchedule;
import dao.BaseDao;

import java.util.List;
import java.util.Optional;

/**
 * 课程数据访问接口，继承 BaseDao，提供课程及排课相关的数据库操作。
 */
public interface CourseDao extends BaseDao<Course,Long> {

    /**
     * 根据课程ID查找课程及其排课信息
     * @param id 课程ID
     * @return 包含排课信息的课程，若不存在返回 Optional.empty()
     */
    Optional<Course> findByIdWithSchedules(Long id);

    /**
     * 查询所有课程及其排课信息
     * @return 包含排课信息的课程列表
     */
    List<Course> findAllWithSchedules();

    /**
     * 根据学期查询课程
     * @param sm 学期
     * @return 指定学期的课程列表
     */
    List<Course> findBySemester(Semester sm);

    /**
     * 根据教师姓名查询课程
     * @param TeacherName 教师姓名
     * @return 该教师教授的课程列表
     */
    List<Course> findByTeacherName(String TeacherName);

    /**
     * 根据课程代码查询课程
     * @param CourseCode 课程代码
     * @return 匹配课程代码的课程列表
     */
    List<Course> findByCourseCode(String CourseCode);

    /**
     * 根据课程名称查询课程
     * @param CourseName 课程名称
     * @return 匹配课程名称的课程列表
     */
    List<Course> findByCourseName(String CourseName);

    /**
     * 查询指定学生已选课程
     * @param studentId 学生ID
     * @return 学生已选的课程列表
     */
    List<Course> findSelectedCourseByStudentId(Long studentId);

    /**
     * 查询指定课程的学生列表
     * @param courseId 课程ID
     * @return 选修该课程的学生列表
     */
    List<Student> findStudentsByCourseId(Long courseId);

    /**
     * 查询状态为启用的课程
     * @return 状态为 true 的课程列表
     */
    List<Course> findStatusTrue();

    /**
     * 查询可进行排课的课程
     * @return 可进行排课的课程列表
     */
    List<Course> findCoursesToSchedule();

    /**
     * 选课操作：课程人数加一
     * @param courseId 课程ID
     * @return 是否成功
     */
    boolean incrementEnrollment(Long courseId);

    /**
     * 退课操作：课程人数减一
     * @param courseId 课程ID
     * @return 是否成功
     */
    boolean decrementEnrollment(Long courseId);

    /**
     * 检查学生是否已选该课程
     * @param courseId 课程ID
     * @param studentId 学生ID
     * @return 若已选返回 true，否则返回 false
     */
    boolean isStudentEnrolled(Long courseId, Long studentId);

    /**
     * 将学生加入课程选课表
     * @param courseId 课程ID
     * @param studentId 学生ID
     * @return 是否成功
     */
    boolean enrollStudentInCourseTable(Long courseId, Long studentId);

    /**
     * 将学生从课程选课表移除
     * @param courseId 课程ID
     * @param studentId 学生ID
     * @return 是否成功
     */
    boolean dropStudentFromCourseTable(Long courseId, Long studentId);
}
